package com.vaadin.tutorial.crm.ui.view.list;

import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.shared.Registration;
import com.vaadin.tutorial.crm.backend.entity.Teacher;
import com.vaadin.tutorial.crm.backend.util.CommonComponent;

/**
 * 表单
 * @Author: fan
 * @DateTime: 2021-01-14 15:09
 **/
//FormLayout根据窗口宽度将表单字段显示为一列或者两列
public class TeacherForm extends FormLayout {
    private Teacher teacher;

    //通过Binder 来绑定表单字段到数据对象，注意两者属性名称要一致
    Binder<Teacher> binder =  new BeanValidationBinder<>(Teacher.class);

    //输入框
    TextField teacherNum = new TextField("老师编号");
    TextField teacherName = new TextField("老师姓名");
    TextField teacherPhone = new TextField("联系电话");
    //按钮
    Button save = new Button("Save");
    Button delete = new Button("Delete");
    Button close = new Button("Cancel");

    //模态框
    public static Dialog dialog;

    public TeacherForm() {
        addClassName("teacher-form");
        //绑定数据到组件
        binder.bindInstanceFields(this);

        //添加组件到布局
        this.add(teacherNum,
                teacherName,
                teacherPhone,
                createButtonsLayout());
    }

    //HorizontalLayout 使用水平布局使得按钮一个紧挨一个水平排放
    private HorizontalLayout createButtonsLayout() {
        save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
        close.addThemeVariants(ButtonVariant.LUMO_TERTIARY);

        save.addClickShortcut(Key.ENTER);
        close.addClickShortcut(Key.ESCAPE);

        //save、delete、close按钮的事件
        save.addClickListener(event -> validateAndSave());
        delete.addClickListener(event -> openDialog());
        close.addClickListener(event -> fireEvent(new CloseEvent(this)));

        binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid()));
        return new HorizontalLayout(save, delete, close);
    }

    // readBean将值从Teacher复制到内部模型（最后赋值给表单），这样，如果我们取消编辑，就不会意外覆盖值
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
        binder.readBean(teacher);
    }

    //事件，监听表单中组件值的变化
    // Events
    public static abstract class TeacherFormEvent extends ComponentEvent<TeacherForm> {
        private Teacher teacher;

        protected TeacherFormEvent(TeacherForm source, Teacher teacher) {
            super(source, false);
            this.teacher = teacher;
        }

        public Teacher getTeacher() {
            return teacher;
        }
    }

    public static class SaveEvent extends TeacherFormEvent {
        SaveEvent(TeacherForm source, Teacher teacher) {
            super(source, teacher);
            CommonComponent.open_notifi("新增成功！");
        }
    }

    public static class DeleteEvent extends TeacherFormEvent {
        DeleteEvent(TeacherForm source, Teacher teacher) {
            super(source, teacher);
            CommonComponent.open_notifi("删除成功！");
            dialog.close();
        }
    }

    public static class CloseEvent extends TeacherFormEvent {
        CloseEvent(TeacherForm source) {
            super(source, null);
        }
    }

    public <T extends ComponentEvent<?>> Registration addListener(Class<T> eventType,
                                                                  ComponentEventListener<T> listener) {
        return getEventBus().addListener(eventType, listener);
    }

    private void validateAndSave() {
        try {
            binder.writeBean(teacher);
            fireEvent(new SaveEvent(this, teacher));
        } catch (ValidationException e) {
            e.printStackTrace();
        }
    }

    //删除时弹出的模态框
    public void openDialog(){
        dialog = CommonComponent.createDialog("200px", "130px");
        Div div = CommonComponent.createDiv("确认删除吗？", "margin-left", "30px");
        Button confirm = new Button(new Span("确认"), event -> fireEvent(new DeleteEvent(this, teacher)));
        confirm.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        confirm.getStyle().set("right", "15px");
        Button cancel = new Button(new Span("取消"), event -> dialog.close());
        cancel.addThemeVariants(ButtonVariant.LUMO_ERROR);
        Div div1 = CommonComponent.createDiv("", "margin-left", "40px");
        div1.add(confirm, cancel);
        dialog.add(
                div,
                div1
        );
        dialog.open();
    }
}
